package ktvcmdserver

import (
	"encoding/binary"
	//"fmt"
	"bytes"
	"ktvserver/core/session"
	"ktvserver/core/udpserver"
	"ktvserver/ktvutil"
	"log"
	"strings"
	"time"
)

// 在线下载用户协议

// 用户登录响应信息
type KtvUserLoginRsp struct {
	Token          uint64 // 令牌
	Result         int32  // 登录结果
	ExpirationDate uint32 // 过期时间
	MaxSpeed       uint32 // 最大的速率
	NowDate        uint32 // 当前时间
}

/////////////////////////////////////////////////////////////////////////////////
//用户登录
// CMD_PUBLIC_LOGIN
func KtvPublicUserLogin(w udpserver.ResponseWriter, req *udpserver.Request) {

	//fmt.Printf("KtvPublicUserLogin  ")

	totalLen := req.Rd.Len()

	// 检查是否附带了注册码之类的信息
	//
	if totalLen <= req.CmdMessage.StructSize() {
		// 不响应信息
		return
	}

	// 读取注册码信息
	left := totalLen - req.CmdMessage.StructSize()
	textBytes := make([]byte, left+2)
	req.Rd.Seek(int64(req.CmdMessage.StructSize()), 0)
	req.Rd.Read(textBytes)

	// appendText 已经是utf8编码的文本
	appendText := ktvutil.Utf16ByteToUtf8(textBytes)

	// 注册码#MAC
	userCode := ""
	userMAC := ""

	dataArray := strings.Split(appendText, "#")
	if len(dataArray) >= 1 {
		userCode = dataArray[0]
	}

	if len(dataArray) >= 2 {
		userMAC = dataArray[1]
	}

	var cmd udpserver.KtvCmdMessage
	var rsp KtvUserLoginRsp

	cmd.Reset()
	cmd.Cmd = CMD_PUBLIC_LOGIN
	rsp.Result = session.KTV_SESSION_STATUS_INVALID

	strShowCode := userCode
	if len(strShowCode) > 10 {
		strShowCode = strShowCode[0:10]
	}

	// 开始登录到系统
	result, token := session.Login(userCode, userMAC, req.RemoteAddr.String())
	log.Printf("(%s) Login result=%d, code=%s\n", req.RemoteIP(), result, strShowCode)
	if result == session.KTV_SESSION_STATUS_OK {
		// 登陆成功
		sess := session.GetSession(token)
		if sess != nil {
			//fmt.Println("login ok")
			rsp.Token = token
			rsp.Result = int32(result)
			rsp.ExpirationDate = uint32(sess.GetExpirationDate())
			rsp.MaxSpeed = uint32(sess.GetSpeed())
			rsp.NowDate = uint32(time.Now().Unix())
		} else {
			log.Println("Unkown error")
		}
	}

	// 写入响应数据
	binary.Write(w, binary.LittleEndian, &cmd)
	binary.Write(w, binary.LittleEndian, &rsp)

}

// 用户网络心跳
// CMD_PUBLIC_HEARTBEAT
func KtvPublicUserHeartbeat(w udpserver.ResponseWriter, req *udpserver.Request) {

	totalLen := req.Rd.Len()

	//
	if totalLen <= req.CmdMessage.StructSize() {
		// 不响应信息
		return
	}

	//
	//left := totalLen - req.CmdMessage.StructSize()
	textBytes := make([]byte, 8)
	req.Rd.Seek(int64(req.CmdMessage.StructSize()), 0)
	req.Rd.Read(textBytes)

	var token uint64
	buf := bytes.NewBuffer(textBytes)
	binary.Read(buf, binary.LittleEndian, &token)

	newStatus := session.Heartbeat(token, req.RemoteAddr.String())

	//log.Printf("Heartbeat,token=%x, status=%d", token, newStatus)

	var cmd udpserver.KtvCmdMessage

	// 响应当前的状态
	cmd.Reset()
	cmd.Cmd = CMD_PUBLIC_HEARTBEAT
	binary.Write(w, binary.LittleEndian, &cmd)
	binary.Write(w, binary.LittleEndian, &newStatus)

}

// 用户报告准备完毕消息
// CMD_PUBLIC_USER_STANDBY
func KtvPublicUserStandby(w udpserver.ResponseWriter, req *udpserver.Request) {

}

// 用户报告准备完毕消息
// CMD_PUBLIC_RELOAD_BLACK_LIST
func KtvPublicReloadBlackList(w udpserver.ResponseWriter, req *udpserver.Request) {

}
